﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;

namespace LcfContols
{
    /// <summary>
    /// 总汇行
    /// </summary>
    public class LDataGridViewSumRow : Control
    {
        #region 变量
        /// <summary>
        /// 水平滚动条
        /// </summary>
        private ScrollBar hScroll ;

        /// <summary>
        /// 相关的数据表
        /// </summary>
        private DataGridView DataGridView;

        private int[] _sumColumnsIndex;

        /// <summary>
        /// 列数据统计内容
        /// </summary>
        private Dictionary<int, decimal> sumColumnsSum = new Dictionary<int, decimal>();


        /// <summary>
        /// 只是编辑完成后是否自动更新数据
        /// </summary>
        private bool _CellEndEditUpdateSummery = false;

        #endregion

        #region
        /// <summary>
        /// 要统计的列索引
        /// </summary>
        internal int[] sumColumnsIndex
        {
            get
            {
                return _sumColumnsIndex;
            }
            set{
                _sumColumnsIndex = value;
            }
        }
        
        /// <summary>
        /// 统计的数据，Key为列索引
        /// 用来手动统计数据
        /// </summary>
        internal Dictionary<int,decimal> ColumnsSum
        {
            get
            {
                return sumColumnsSum;
            }
        }

        /// <summary>
        /// 编辑完成后是否自动更新统计数据
        /// </summary>
        internal bool CellEndEditUpdateSummery {
            get
            {
                return _CellEndEditUpdateSummery;
            }
            set
            {
                DataGridView.CellEndEdit -= DataGridView_CellEndEdit;
                _CellEndEditUpdateSummery = value;
                if(value)
                    DataGridView.CellEndEdit += DataGridView_CellEndEdit;
            }
        }

        #endregion

        public LDataGridViewSumRow(DataGridView DataGridView)
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true);
            this.DataGridView = DataGridView;
            DataGridView.RowHeadersWidthChanged += DataGridView_RowHeadersWidthChanged;
            DataGridView.ColumnWidthChanged += DataGridView_ColumnWidthChanged;
            ForeColor = Color.Red;
        }

        /// <summary>
        /// 修改键值后更新统计数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if(sumColumnsIndex != null && sumColumnsIndex.Contains(e.ColumnIndex))
            {
                try
                {
                    sumColumnsSum[e.ColumnIndex] += Convert.ToDecimal(DataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value);
                    DrawSummery(false, e.ColumnIndex);
                }catch(Exception ex)
                {
#if DEBUG
                    Console.WriteLine(ex.Message);
#endif
                }
            }
        }

        /// <summary>
        /// 水平滚动条
        /// </summary>
        /// <param name="value"></param>
        public void HScrollSet(HScrollBar value)
        {
            hScroll = value;
            hScroll.ValueChanged += HScroll_ValueChanged;
        }

        private void HScroll_ValueChanged(object sender, EventArgs e)
        {
            //滚动值改变了就进行重绘
            Invalidate();
        }
        
        private void DataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            Invalidate();//重绘
        }

        private void DataGridView_RowHeadersWidthChanged(object sender, EventArgs e)
        {
            //宽度改变，控件重绘
            Invalidate(); //重绘
        }

        /// <summary>
        /// 重绘数据
        /// </summary>
        /// <param name="drawAll"></param>
        /// <param name="columnIndex"></param>
        private void DrawSummery(bool drawAll,int columnIndex)
        {
            if (!drawAll && (sumColumnsIndex == null || !sumColumnsSum.ContainsKey(columnIndex)))
                return; //如果索引为空或者没有进行手工统计初始化，则直接返回
            int x = DataGridView.RowHeadersWidth;
            int height = Height;
            int MaxScrollX = hScroll.Maximum - Width + DataGridView.RowHeadersWidth + 2;
            if (hScroll != null && hScroll.Visible)
                x -= Math.Min(hScroll.Value, MaxScrollX);
            //绘制各个列
            foreach (DataGridViewColumn column in DataGridView.Columns)
            {
                x += column.Width; //列右侧X坐标
                if ((!drawAll && column.Index != columnIndex) || !sumColumnsSum.ContainsKey(column.Index))
                    continue;
                using (Graphics g = Graphics.FromHwnd(this.Handle))
                {
                    Rectangle value = new Rectangle(x - column.Width, 1, column.Width-1, height);
                    using (SolidBrush brush = new SolidBrush(DataGridView.DefaultCellStyle.BackColor))
                    {
                        g.FillRectangle(brush, value); //填充单元格
                    }
                    g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                    Size s = TextRenderer.MeasureText(String.Format("{0}", sumColumnsSum[column.Index]), Font);
                    if (column.Width < s.Width + 5)
                        column.MinimumWidth = s.Width + 5;
                    using (SolidBrush brush = new SolidBrush(ForeColor))
                    {
                        g.DrawString(String.Format("{0}", sumColumnsSum[column.Index]), Font, brush, new Point(x - s.Width - 2, (height - s.Height) / 2));
                    }
                }
            }
        }
        
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            BackColor = DataGridView.BackgroundColor;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            int x=DataGridView.RowHeadersWidth;
            int y = 1;
            int height = Height;
            int MaxScrollX = hScroll.Maximum - Width + DataGridView.RowHeadersWidth;
            if (hScroll.Visible)
                x -= Math.Min(hScroll.Value, MaxScrollX);
            //绘制各个列
            foreach (DataGridViewColumn column in DataGridView.Columns)
            {
                x += column.Width; //列右侧X坐标
                Rectangle value = new Rectangle(x - column.Width, y, column.Width, height);
                using(SolidBrush brush=new SolidBrush(DataGridView.DefaultCellStyle.BackColor))
                {
                    g.FillRectangle(brush, value); //填充单元格
                }
                if (sumColumnsSum.ContainsKey(column.Index)){
                    Size s = TextRenderer.MeasureText(String.Format("{0}", sumColumnsSum[column.Index]), Font);
                    using(SolidBrush brush=new SolidBrush(ForeColor))
                    {
                        g.DrawString(String.Format("{0}", sumColumnsSum[column.Index]), Font, brush, new Point(x - s.Width - 2,(height-s.Height)/2));
                    }
                }
                g.DrawLine(SystemPens.ControlDark, new Point(x-1, 0), new Point(x-1, Bottom)); 
            }
            ///因为滚动时候标题是不变的，所以只有在把列按动态位置绘制出来后再绘制标题。不然列的滚动偏移绘制会覆盖标题内容
            x = DataGridView.RowHeadersWidth;
            DataGridViewRow row = DataGridView.RowTemplate;
            Size Textsize = TextRenderer.MeasureText("总汇", Font);
            using (SolidBrush brush = new SolidBrush(DataGridView.RowHeadersDefaultCellStyle.BackColor))
            {
                g.FillRectangle(brush, new Rectangle(0, 1, x, height)); //填充单元格
            }
            using(SolidBrush brush=new SolidBrush(ForeColor))
            { 
                g.DrawString("总汇", Font, brush, new Point((x - Textsize.Width) / 2, (height - Textsize.Height) / 2));
            }
            g.DrawLine(SystemPens.ControlDark, new Point(x - 1, 0), new Point(x - 1, Bottom)); //画右侧的线条
        }
        
        /// <summary>
        /// 手动统计数据
        /// <param name="update">直接更新数据</param>
        /// </summary>
        internal void Summery(bool update=false)
        {
            if (update)
            {
                DrawSummery(true, 0); //直接更新数据，当手动设置统计数据时直接更新
                return;
            }
            if (sumColumnsIndex == null)
                return;
            sumColumnsSum.Clear();
            foreach(int i in sumColumnsIndex){
                sumColumnsSum.Add(i, 0);
            }
            foreach(DataGridViewRow row in DataGridView.Rows)
            {
                foreach(int i in sumColumnsIndex)
                {
                    try
                    {
                        sumColumnsSum[i] += Convert.ToDecimal(row.Cells[i].Value);
                    }catch(Exception ex)
                    {
#if DEBUG
                        Console.WriteLine(ex.Message);
#endif
                    }
                }
            }
            DrawSummery(true,0); //更新数据
        }

    }
}
